package com.hatic.money;

import java.util.List;
import java.util.Map;

import org.jxstar.dao.DaoParam;
import org.jxstar.service.BusinessObject;

/**
 * 投资计划合并实施处理，合并实施的规则是：
 * 必须是同项目类别、同授权形式、同实施单位、同预算年度的“待实施”状态的计划；
 * 
 * 被合并的计划可能是某个虚拟包的子计划，
 * 则被合并的计划必须都是同一个虚拟包中的计划，处理这个问题主要是保证虚拟包的统计数据是准确的；
 * 
 * 合并实施提交后：
 * 将产生一个项目立项申请，相关子计划中止，并且相关计划的立项申请自动删除；
 *
 * @author TonyTan
 * @version 1.0, 2011-10-16
 */
public class PlanDoBaoBO extends BusinessObject {
	private static final long serialVersionUID = 1L;

	public String addBaoPlan(String[] planIds, String parentId) {
		if (planIds == null || planIds.length == 0) {
			setMessage("没有选择投资计划包！");
			return _returnFaild;
		}
		
		//用于判断当前选择的投资计划是否同属一个虚拟包，或者都不是子计划
		String oldparentid = "", allfileno = "";
		
		String bao_type = "";
		String plan_parentid = "";
		String plan_parentcode = "";
		String check_fileno = "";
		String money_type2 = "";
		
		for (int i = 0, n = planIds.length; i < n; i++) {
			Map<String,String> subdata = queryPlan(planIds[i]);
			bao_type = subdata.get("bao_type");
			plan_parentid = subdata.get("plan_parentid");
			plan_parentcode = subdata.get("plan_parentcode");
			check_fileno = subdata.get("check_fileno");
			money_type2 = subdata.get("money_type2");
			
			//添加批复文号，如果存在则不添加
			if (allfileno.length() == 0) {
				allfileno = check_fileno;
			} else {
				if (allfileno.indexOf(check_fileno) < 0) {
					allfileno += check_fileno;
				}
			}
			
			//用于判断当前选择的投资计划是否同属一个虚拟包，或者都不是子计划
			if (oldparentid.length() == 0 && plan_parentid.length() > 0) {
				oldparentid = plan_parentid;
			} else {
				if (!checkBaoType(oldparentid, plan_parentid)) return _returnFaild;
			}

			if (!addOnePlan(planIds[i], parentId)) {
				setMessage("添加投资计划包的子计划失败！");
				return _returnFaild;
			}
		}
		
		//更新当前父计划包的包属性，存在选择的子计划都是某个虚拟包的子计划的情况，
		//所以需要把子计划的虚拟包信息写到当前实施包中
		if (!updateParent(plan_parentid, plan_parentcode, bao_type, 
				parentId, allfileno, money_type2)) {
			setMessage("更新当前父计划包的包属性失败！");
			return _returnFaild;
		}
		
		//更新父计划中的金额信息
		(new PlanMemoBO()).updateSum(parentId);
		
		return _returnSuccess;
	}
	
	/**
	 * 包提交效验，提交后需要创建新的项目立项记录，同时删除子计划的项目立项记录
	 * @param planIds
	 * @return
	 */
	public String auditBao(String[] planIds, String userId) {
		if (planIds == null || planIds.length == 0) {
			setMessage("没有选择投资计划包！");
			return _returnFaild;
		}
		
		PlanAuthBO planbo = new PlanAuthBO();
		
		for (int i = 0, n = planIds.length; i < n; i++) {
			String parentId = planIds[i];
			//效验子计划是否同属一个包中
			if (!checkOneBao(parentId)) return _returnFaild;
			
			if (!updateMoney(parentId)) {
				setMessage("更新计划包的金额与状态出错！");
				return _returnFaild;
			}
			
			//更新子计划的父计划编码、与计划状态改为中止
			if (!updateSubPlan(parentId)) {
				setMessage("更新子计划的状态出错！");
				return _returnFaild;
			}
			
			//删除子计划的立项申请
			if (!deleteProject(parentId)) {
				setMessage("删除子计划的立项申请出错！");
				return _returnFaild;
			}
			
			//产生计划包的立项申请
			if (!planbo.projectCreate(parentId, userId)) {
				setMessage("投资计划包创建项目立项申请出错！");
				return _returnFaild;
			}
		}
		
		return _returnSuccess;
	}
	
	/**
	 * 包删除，恢复子计划的父计划ID
	 * @param planIds
	 * @return
	 */
	public String deleteBao(String[] planIds) {
		if (planIds == null || planIds.length == 0) {
			setMessage("没有选择投资计划包！");
			return _returnFaild;
		}
		
		for (int i = 0, n = planIds.length; i < n; i++) {
			deleteSub(planIds[i]);
		}
		
		return _returnSuccess;
	}
	
	//删除包明细记录
	public String delsub(String[] planIds) {
		if (planIds == null || planIds.length == 0) {
			setMessage("没有选择子投资计划！");
			return _returnFaild;
		}
		
		Map<String,String> plandata = queryPlan(planIds[0]);
		String parentId = plandata.get("plan_parentid");
		
		for (int i = 0, n = planIds.length; i < n; i++) {
			delSub(planIds[i]);
		}
		
		//更新父计划中的金额信息
		(new PlanMemoBO()).updateSum(parentId);
		
		return _returnSuccess;
	}
	
	//更新子计划的立项申请为中止
	/*private boolean updateProject(String parentId) {
		String sql = "update project_base set project_status = '9' where plan_id in " +
					 "(select plan_id from money_plan where plan_parentid = ?)";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(parentId);
		
		return _dao.update(param);
	}*/
	
	//删除被合并实施的立项申请
	private boolean deleteProject(String parentId) {
				String sql = "delete from project_base where plan_id in " +
				 "(select plan_id from money_plan where plan_parentid = ?)";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(parentId);
		
		return _dao.update(param);
	}
	
	//更新子计划的父计划编码、与计划状态改为中止
	private boolean updateSubPlan(String parentId) {
		//取父计划编码
		Map<String,String> parentData = queryPlan(parentId);
		String plancode = parentData.get("plan_code");
		
		String sql = "update money_plan set plan_parentcode = ?, plan_status = '92' " +
			"where plan_parentid = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(plancode);
		param.addStringValue(parentId);
		
		return _dao.update(param);
	}
	
	//判断当前选择的投资计划是否同属一个虚拟包，或者都不是子计划
	private boolean checkOneBao(String parentId) {
		List<Map<String,String>> lsdata = querySubPlan(parentId);
		if (lsdata.isEmpty()) {
			setMessage("当前投资计划包中没有选择子投资计划！");
			return false;
		}
		
		if (lsdata.size() < 2) {
			setMessage("当前投资计划包中选择的子投资计划数量小于2，不能提交！");
			return false;
		}
		
		//用于判断当前选择的投资计划是否同属一个虚拟包，或者都不是子计划
		String oldparentid = "";
		String plan_parentid = "";
		
		for (int i = 0, n = lsdata.size(); i < n; i++) {
			Map<String,String> mpdata = lsdata.get(i);
			plan_parentid = mpdata.get("plan_oldparentid");
			
			if (oldparentid.length() == 0 && plan_parentid.length() > 0) {
				oldparentid = plan_parentid;
			} else {
				if (!checkBaoType(oldparentid, plan_parentid)) return false;
			}
		}
		
		return true;
	}
	
	//更新计划包的金额与状态
	private boolean updateMoney(String parentId) {
		String sql = "select sum(plan_money) as plan_money, sum(year_money) as year_money " +
			"from money_plan where plan_parentid = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(parentId);
		Map<String,String> mpSum = _dao.queryMap(param);
		
		double plan_money = tonum(mpSum.get("plan_money"));
		double year_money = tonum(mpSum.get("year_money"));
		
		String usql = "update money_plan set plan_money = ?, year_money = ?, plan_status = '41' where plan_id = ?";
		DaoParam uparam = _dao.createParam(usql);
		uparam.addDoubleValue(Double.toString(plan_money));
		uparam.addDoubleValue(Double.toString(year_money));
		uparam.addStringValue(parentId);
		return _dao.update(uparam);
	}
	
	//字符串转换为数字
	private double tonum(String num) {
		if (num == null || num.length() == 0) return 0;
		
		return Double.parseDouble(num);
	}
	
	//删除时恢复父计划ID
	private boolean deleteSub(String parentId) {
		String sql = "update money_plan set plan_parentid = plan_oldparentid, plan_oldparentid = '' where plan_parentid = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(parentId);
		
		return _dao.update(param);
	}
	
	//删除时恢复父计划ID
	private boolean delSub(String planId) {
		String sql = "update money_plan set plan_parentid = plan_oldparentid, plan_oldparentid = '' where plan_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(planId);
		
		return _dao.update(param);
	}
	
	//更新父计划包的包属性
	private boolean updateParent(String parentid, String parentcode, String baotype, 
			String planid, String fileno, String money_type2) {
		String sql = "update money_plan set plan_parentid = ?, plan_parentcode = ?, bao_type = ?, " +
				"check_fileno = ?, money_type2 = ? where plan_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(parentid);
		param.addStringValue(parentcode);
		param.addStringValue(baotype);
		param.addStringValue(fileno);
		param.addStringValue(money_type2);
		param.addStringValue(planid);
		
		return _dao.update(param);
	}
	
	/**
	 * 包属性判断
	 * @param oldparentid -- 比较值
	 * @param parentid -- 当前值
	 * @return
	 */
	private boolean checkBaoType(String oldparentid, String parentid) {
		if (parentid.length() > 0) {
			if (oldparentid.length() > 0) {
				if (!parentid.equals(oldparentid)) {
					setMessage("被合并的投资计划必须同属一个虚拟包，或者都不是子计划，当前选择的计划不符合条件！");
					return false;
				}
			}
		} else {
			if (oldparentid.length() > 0) {
				setMessage("被合并的投资计划必须同属一个虚拟包，或者都不是子计划，当前选择的计划不符合条件！");
				return false;
			}
		}
		return true;
	}
	
	/**
	 * 更新子计划的新的父计划ID
	 * plan_oldparentid 记录原父计划ID
	 * plan_parentcode  这个值在提交时更新
	 * 
	 * @param planId
	 * @param parentId
	 * @return
	 */
	private boolean addOnePlan(String planId, String parentId) {
		String sql = "update money_plan set plan_oldparentid = plan_parentid, plan_parentid = ? where plan_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(parentId);
		param.addStringValue(planId);
		
		return _dao.update(param);
	}
	
	//取计划的包属性相关字段
	private Map<String,String> queryPlan(String planId) {
		String sql = "select plan_code, plan_parentid, plan_parentcode, bao_type, check_fileno, " +
				"money_type2 from money_plan where plan_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(planId);
		
		return _dao.queryMap(param);
	}
	
	//取所有子计划的包属性相关字段
	private List<Map<String,String>> querySubPlan(String parentId) {
		String sql = "select plan_oldparentid from money_plan where plan_parentid = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(parentId);
		
		return _dao.query(param);
	}
}
